using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using SharpMud.MudLib.Common.Entities;

namespace SharpMud.MudLib.Common.Entities.Players.Persistance
{
    [XmlRoot("PlayerCharacterLoaderMetadatum")]
    public class PlayerCharacterLoaderMetadatum<TPlayerCharacterInstance> where TPlayerCharacterInstance : IPlayerCharacter, new()
    {
        #region Private Variables
        private string _FolderPath;
        private string _Extension;
        private bool _Recursive;
        private string _PlayerCharacterStreamer;
        #endregion

        #region Constructors
        public PlayerCharacterLoaderMetadatum()
        {
            _FolderPath = "";
            _Extension = "*.*";
            _Recursive = false;
            _PlayerCharacterStreamer = "";
        }
        #endregion

        #region Public Properties
        [XmlElement("FolderPath")]
        public string FolderPath
        {
            get
            {
                return _FolderPath;
            }
            set
            {
                _FolderPath = value;
            }
        }
        [XmlElement("Extension")]
        public string Extension
        {
            get
            {
                return _Extension;
            }
            set
            {
                _Extension = value;
                _Extension = _Extension.Trim();
                if(_Extension.StartsWith("*."))
                {
                    _Extension = _Extension.Substring(1);
                }
                if (!_Extension.StartsWith("."))
                {
                    _Extension = "." + _Extension;
                }
            }
        }
        [XmlElement("Recursive")]
        public bool Recursive
        {
            get
            {
                return _Recursive;
            }
            set
            {
                _Recursive = value;
            }
        }
        [XmlElement("PlayerCharacterStreamerType")]
        public string PlayerCharacterStreamer
        {
            get
            {
                return _PlayerCharacterStreamer;
            }
            set
            {
                _PlayerCharacterStreamer = value;
            }
        }
        [XmlIgnore()]
        public System.Type PlayerCharacterStreamerType
        {
            get
            {
                return System.Type.GetType(_PlayerCharacterStreamer, false, true);
            }
            set
            {
                _PlayerCharacterStreamer = value.AssemblyQualifiedName;
            }
        }
        #endregion

        #region Public Methods
        public System.IO.FileInfo[] GetApplicableFiles(string rootDirectory)
        {
            string searchPattern = this._Extension.Trim();
            if (!searchPattern.StartsWith("*."))
            {
                if (!searchPattern.StartsWith("."))
                {
                    searchPattern = "." + searchPattern;
                }
                if (!searchPattern.StartsWith("*"))
                {
                    searchPattern = "*" + searchPattern;
                }
            }

            string dir = System.IO.Path.Combine(rootDirectory, this._FolderPath);
            if (!System.IO.Directory.Exists(dir))
            {
                throw new System.IO.DirectoryNotFoundException("The directory \"" + dir + "\" does not exist.");
            }

            List<System.IO.FileInfo> filesFound = new List<System.IO.FileInfo>();
            System.IO.SearchOption so;

            if (this.Recursive)
                so = System.IO.SearchOption.AllDirectories;
            else
                so = System.IO.SearchOption.TopDirectoryOnly;

            System.IO.DirectoryInfo thisDirectory = new System.IO.DirectoryInfo(dir);
            foreach (System.IO.FileInfo fi in thisDirectory.GetFiles(searchPattern, so))
            {
                filesFound.Add(fi);
            }
            return filesFound.ToArray();
        }
        public IPlayerCharacterStreamer<TPlayerCharacterInstance> GetPlayerCharacterStreamer()
        {
            if (this._PlayerCharacterStreamer == null || this._PlayerCharacterStreamer == String.Empty)
            {
                return null;
            }
            if (this.PlayerCharacterStreamerType == null)
                return null;

            object obj = this.PlayerCharacterStreamerType.Assembly.CreateInstance(this.PlayerCharacterStreamerType.FullName, false);
            return ((IPlayerCharacterStreamer<TPlayerCharacterInstance>)obj);
        }
        public System.IO.FileSystemWatcher GetFileSystemWatcher()
        {
            string searchPattern = this._Extension.Trim();
            if (!searchPattern.StartsWith("*."))
            {
                if (!searchPattern.StartsWith("."))
                {
                    searchPattern = "." + searchPattern;
                }
                if (!searchPattern.StartsWith("*"))
                {
                    searchPattern = "*" + searchPattern;
                }
            }

            System.IO.FileSystemWatcher fsw = new System.IO.FileSystemWatcher(this._FolderPath, searchPattern);
            fsw.IncludeSubdirectories = this._Recursive;
            return fsw;
        }
        #endregion
    }
}
